package trc.model;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author dZ
 */
public class Layers implements Iterable<Layer> {

    public static class ChangeEvent {
        private boolean recalculated;
                
        public ChangeEvent(Boolean recalculated) {
            this.recalculated = recalculated;
        }

        public boolean isRecalculated() {
            return recalculated;
        }
    }
    
    public interface ChangeListener {
        public void layersChanged(ChangeEvent event);
    }
    
    
    private List<ChangeListener> listenres;
    
    public final void addEventListener(ChangeListener listener) {
        if(this.listenres == null) {
            this.listenres = new ArrayList<ChangeListener>();
        }
        
        this.listenres.add(listener);
    }
    
    public final void removeEventListener(ChangeListener listener) {
        if(this.listenres == null) return;
        
        this.listenres.remove(listener);
    }

    private void fireLayersChangedEvent(boolean recalculated) {
        if(this.listenres != null && !this.listenres.isEmpty()) {
            ChangeEvent event = new ChangeEvent(recalculated);
            
            for(ChangeListener listener: listenres) {
                listener.layersChanged(event);
            }
        }
    }

    
    private List<Layer> list = new ArrayList<Layer>();
    
    public final void add(Layer layer) {
        this.add(layer, true);
    }
    
    private void add(Layer layer, boolean needsRecalc) {
        list.add(layer);
        layer.addPropertyChangeListener(layerListener);
        if(needsRecalc) fireLayersChangedEvent(true);
    }
    
    public final void remove(Layer layer) {
        layer.removePropertyChangeListener(layerListener);
        list.remove(layer);
        fireLayersChangedEvent(true);
    }
    
    public final void clear() {
        for(Layer layer: list) {
            layer.removePropertyChangeListener(layerListener);
        }
        
        this.list.clear();
        
        fireLayersChangedEvent(true);
    }
    
    public final void init(Layer[] layers) {
        this.clear();
        
        for(Layer layer: layers) {
            this.add(layer, false);
        }
        
        fireLayersChangedEvent(true);
    }
    
    public final Layer get(int index) {
        return this.list.get(index);
    }
    
    public final int indexOf(Layer layer) {
        return this.list.indexOf(layer);
    }
    
    public final int size() {
        return this.list.size();
    }
    
     @Override
    public Iterator<Layer> iterator() {
         return this.list.iterator();
    }
    
   
    private PropertyChangeListener layerListener = new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            boolean needsRecalc = Layer.PROP_LAMBDA.equalsIgnoreCase(evt.getPropertyName()) || Layer.PROP_THICKNESS.equalsIgnoreCase(evt.getPropertyName());
            fireLayersChangedEvent(needsRecalc);
        }
    };
}